package persi.reporte;

import org.hibernate.Criteria;
import org.hibernate.criterion.LogicalExpression;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.SimpleExpression;
import org.hibernate.transform.BasicTransformerAdapter;

import persi.futbol.Equipo;
import persi.futbol.partidos.PartidoSimple;
import persi.hibernate.Home;

public class ReporteEstadisticoEntre2Equipos extends
		AbstractReporter<PartidoSimple> {
	public class MiReporterPrinter extends AbstractReporter.ReporterPrinter {

		public MiReporterPrinter(Equipo equipo, Long cantidad) {
			super(equipo, cantidad);
		}

		@Override
		public String toString() {
			if (this.getEquipo() == null)
				return "Se empataron " + this.getCantidadGanados()
						+ " partidos";
			return "El equipo " + this.getEquipo().getNombre() + " gano "
					+ this.getCantidadGanados() + " partidos";
		}
	}

	private final Equipo equipo2;
	private final Equipo equipo1;

	public ReporteEstadisticoEntre2Equipos(final Equipo equipo1,
			final Equipo equipo2) {
		super(new Home<PartidoSimple>(PartidoSimple.class));
		this.equipo1 = equipo1;
		this.equipo2 = equipo2;
	}

	@Override
	protected Criteria construirCriterio() {
		final Criteria criterio = this.getHome().crearCriterio();
		final SimpleExpression porEquipo1a = Restrictions.eq("equipo1",
				this.getEquipo1());
		final SimpleExpression porEquipo1b = Restrictions.eq("equipo2",
				this.getEquipo2());
		final LogicalExpression primerEquipo = Restrictions.and(porEquipo1a,
				porEquipo1b);

		final SimpleExpression porEquipo2a = Restrictions.eq("equipo2",
				this.getEquipo1());
		final SimpleExpression porEquipo2b = Restrictions.eq("equipo1",
				this.getEquipo2());
		final LogicalExpression segundoEquipo = Restrictions.and(porEquipo2a,
				porEquipo2b);
		criterio.add(Restrictions.or(primerEquipo, segundoEquipo));
		ProjectionList proyecciones = Projections.projectionList();
		proyecciones.add(Projections.rowCount());
		proyecciones.add(Projections.groupProperty("ganador"));
		criterio.setProjection(proyecciones);
		criterio.setResultTransformer(new BasicTransformerAdapter() {
			private static final long serialVersionUID = -6472821112950272334L;

			@Override
			public Object transformTuple(Object[] tuple, String[] aliases) {
				return new ReporteEstadisticoEntre2Equipos.MiReporterPrinter(
						(Equipo) tuple[1], (Long) tuple[0]);

			}
		});
		return criterio;
	}

	private Equipo getEquipo1() {
		return equipo1;
	}

	private Equipo getEquipo2() {
		return equipo2;
	}

	protected long totalPartidos() {
		return (Long) this.construirCriterio()//
				.setProjection(Projections.rowCount())//
				.uniqueResult();
	}

}
